﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Helper.Business.Implementation;
using Helper.Core.Entity;
using Helper.Business.Repository;
using NHibernate;

using Helper.Infrastructure.Extensions;
using Helper.Infrastructure.Call;

namespace Helper.Business.Implementation
{
    public class CallRepository : RepositoryBase<Call>, ICallRepository
    {
        public IEnumerable<Call> GetAllUserRelated(User user)
        {
            try
            {
                using (ISession session = SessionFactory.OpenSession())
                {
                    using (var transact = session.BeginTransaction())
                    {                        
                        IEnumerable<Call> filtered = null;
                        
                        IList<Call> loadedPost = new List<Call>();  
                
                        List<Call> calls = session.QueryOver<Call>()
                            .Select().List().
                            ToList<Call>();

                        foreach (Call call in calls)
                        {
                            call.Posts = session.QueryOver<Post>()
                                .Where(po => po.ParentCall.Id == call.Id)
                                .List().ToList();

                            loadedPost.Add(call);
                        }                   

                        switch (user.Role)
	                    {
		                    case Hierarchy.Client:
                                    //filtered = lquery != null ? lquery.Where(x => (new List<Dependency> { Dependency.Ambos, Dependency.Cliente }).Contains(x.Posts.Last<Post>().Status.Dependency)) : null;    
                                filtered = loadedPost != null ? loadedPost.Where(x => (x.Author.Id == user.Id)) : null;
                                break;
                            case Hierarchy.ClientSpecial:
                                    //filtered = lquery != null ? lquery.Where(x => (new List<Dependency> { Dependency.Ambos, Dependency.Cliente }).Contains(x.Posts.Last<Post>().Status.Dependency)) : null;    
                                filtered = loadedPost != null ? loadedPost.Where(x => (x.Author.ParentBusiness.Id == user.ParentBusiness.Id)) : null;
                                break;
                            /*
                            case Hierarchy.Operator:
                                    //filtered = lquery != null ? lquery.Where(x => (new List<Dependency>{Dependency.Ambos, Dependency.Empresa}).Contains(x.Posts.Last<Post>().Status.Dependency)) : null;                                
                                break;
                            case Hierarchy.OperatorSpecial:
                                break;
                            case Hierarchy.Administrator:
                                break; 
                            */
                            default:
                                    filtered = loadedPost;
                                break;
	                    }

                        transact.Commit();

                        return filtered.ToList<Call>();                    
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }   
        }

        public IEnumerable<Call> GetAllByOrder(string[] orderProperties)
        {
            try
            {
                using (ISession session = SessionFactory.OpenSession())
                {
                    var lquery = session.QueryOver<Call>().List();


                    if (orderProperties != null)
                    {
                        /*
                        foreach (string prop in orderProperties)
                            lquery = lquery.OrderBy<Call>(prop);
                        */
                    }

                    return lquery.Count<Call>() > 0 ? lquery.ToList<Call>() : null;
                }
            }
            catch (Exception ex)
            {                
                throw new Exception(ex.Message);
            }            
        }

        public IEnumerable<Call> GetAllByFilters(FilterCall Filters, string[] OrderProperties)
        {
            IEnumerable<Call> callOrdered = GetAllByOrder(OrderProperties);
            
            callOrdered = Filters.Username != null ? callOrdered.Where<Call>(item => item.Author.Name.ToUpper().Contains(Filters.Username.ToUpper())) : callOrdered;
            callOrdered = Filters.Businessname != null ? callOrdered.Where<Call>(item => item.Author.ParentBusiness.Name == Filters.Businessname) : callOrdered;
            callOrdered = Filters.InitialDate != null ? callOrdered.Where<Call>(item => item.Timestamp >= Filters.InitialDate) : callOrdered;
            callOrdered = Filters.FinalDate != null ? callOrdered.Where<Call>(item => item.Timestamp <= Filters.FinalDate) : callOrdered;

            return callOrdered;
        }
    }
}
